/**
 * 
 */
package com.alstudio.module;

import java.util.HashMap;
import java.util.Iterator;

import com.alstudio.app.ALLocalEnv;
import com.alstudio.event.ALEventDeliver;
import com.alstudio.utils.log.ALLog;

/**
 * @author alonso lee
 * 
 */
public class ALModuleManager implements BaseModuleWorkingStateObserver {

	// 注册到模块管理器的模块
	private HashMap<String, BaseModule> modules = null;

	// 缺省模块管理器
	private static ALModuleManager defaultModuleManager;

	// 模块工作状态监听器
	private ModuleManagerWorkingStateObserver moduleManagerWorkingStateObserver;

	/**
	 * 获取缺省模块管理器
	 * 
	 * @return
	 */
	public static ALModuleManager getDefaultModuleManager() {
		if (defaultModuleManager == null) {
			defaultModuleManager = new ALModuleManager();
		}
		return defaultModuleManager;
	}

	/**
	 * 创建模块管理器，创建模块管理器工作监听器监听管理器工作状态
	 */
	public ALModuleManager() {
		// TODO Auto-generated constructor stub
		modules = new HashMap<String, BaseModule>();
		// 注册模块管理器工作状态监听器
		moduleManagerWorkingStateObserver = new ModuleManagerWorkingStateObserverImpl();
		// 模块管理器开始工作
		moduleManagerWorkingStateObserver.onModuleManagerStart();

		ALEventDeliver.getDefaultAlEventDeliver().register(this);

	}

	/**
	 * 设置模块管理器工作状态监听器
	 * 
	 * @param moduleManagerWorkingStateObserver
	 *            the moduleManagerWorkingStateObserver to set
	 */
	public void setModuleManagerWorkingStateObserver(
			ModuleManagerWorkingStateObserver moduleManagerWorkingStateObserver) {
		this.moduleManagerWorkingStateObserver = moduleManagerWorkingStateObserver;
	}

	/**
	 * 获取模块管理器工作状态
	 * 
	 * @return the moduleManagerWorkingStateObserver
	 */
	public ModuleManagerWorkingStateObserver getModuleManagerWorkingStateObserver() {
		return moduleManagerWorkingStateObserver;
	}

	/**
	 * 注册功能模块
	 * 
	 * @param module
	 */
	public synchronized void registerModule(BaseModule module) {
		isModuleInitCorrect(module);
		invokeRegisterModule(module);

	}

	/**
	 * 从模块管理器中移除模块
	 * 
	 * @param module
	 *            待移除的模块
	 */
	public synchronized void unregisterModule(BaseModule module) {
		// 首先检查模块是否正常
		isModuleInitCorrect(module);
		// 开始执行移除模块
		invokeUnRegisterModule(module);
	}

	/**
	 * 移除模块管理器中的所有模块
	 */
	public synchronized void unregisterAllModules() {
		invokeUnRegisterAllModules();
	}

	/**
	 * 检测模块指定模块是否注册到管理器
	 * 
	 * @param module
	 *            待检测模块
	 * @return
	 */
	public synchronized boolean isModuleRegistered(BaseModule module) {
		isModuleInitCorrect(module);
		return modules.containsKey(module);
	}

	/**
	 * 投递模块事件到模块管理器，模块管理器将事件投递到对应模块
	 * 
	 * @param event
	 */
	public synchronized void postEventToModuleManager(Object event) {
		invokePostEventToModule(event);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.alstudio.module.BaseModuleWorkingStateObserver#onALEvent(com.alstudio
	 * .module.ModuleEvent)
	 */
	@Override
	public void onALEvent(ModuleEvent event) {
		// TODO Auto-generated method stub
		invokeModuleEvent(event);
	}

	/******************************************* 私有方法开始 ***********************************************/

	/**
	 * 执行注册模块
	 * 
	 * @param module
	 */
	private void invokeRegisterModule(BaseModule module) {

		boolean isModuleRegistered = modules.get(module.getHandleEvent().getSimpleName()) == null ? false
				: true;
		if (!isModuleRegistered) {
			// 还没注册过
			ALLog.i(module.getClass().getSimpleName() + " 可处理的事件类型  "
					+ module.getHandleEvent().getSimpleName());
			modules.put(module.getHandleEvent().getSimpleName(), module);
			module.registerModule(ALLocalEnv.getLocalEnv());
			if (moduleManagerWorkingStateObserver != null) {
				moduleManagerWorkingStateObserver.onModuleRegister(module);
			}
		} else {
			ALLog.i("模块" + module.getClass().getSimpleName() + " 已注册过");
		}
	}

	/**
	 * 执行停止功能模块
	 * 
	 * @param module
	 *            待停止的功能模块
	 */
	private void invokeUnRegisterModule(BaseModule module) {
		// 检测module是否已经注册
		boolean isModuleRegistered = modules.get(module.getHandleEvent().getSimpleName()) == null ? false
				: true;

		if (!isModuleRegistered) {
			ALLog.i("模块" + module.getClass().getSimpleName() + " 并没有注册到模块管理器");
		} else {
			ALLog.i("模块" + module.getClass().getSimpleName() + " 已注册过");
			if (modules.remove(module.getHandleEvent().getSimpleName()) != null) {
				// 关闭模块功能
				module.unregisterModule(null);

				if (moduleManagerWorkingStateObserver != null) {
					moduleManagerWorkingStateObserver
							.onModuleUnregister(module);
				}
				module = null;
			}
		}
	}

	/**
	 * 执行停止已注册启动的模块
	 */
	private void invokeUnRegisterAllModules() {

		if (modules.isEmpty()) {
			return;
		}
		Iterator<String> iter = modules.keySet().iterator();

		while (iter.hasNext()) {
			// BaseModule module = modules.get(iter.next());
			// invokeUnRegisterModule(module);
		}
	}

	/**
	 * 检查模块是否正确初始化
	 * 
	 * @param module
	 */
	private void isModuleInitCorrect(BaseModule module) {
		if (module == null) {
			throw new ALModuleException("module 不能为null");
		}

		if (module.handleEvent == null) {
			throw new ALModuleException("未设置 "
					+ module.getClass().getSimpleName() + "可处理的事件类型");
		}

	}

	/**
	 * 处理模块透传上来的事件
	 * 
	 * @param event
	 */
	private synchronized void invokeModuleEvent(ModuleEvent event) {

		ALLog.i("收到 " + event.getModule().getClass().getSimpleName()
				+ " 模块的事件 " + event.getModuleEventType());
	}

	/**
	 * 检查UI投递的事件是否正确
	 * 
	 * @param event
	 */
	private void isPostingEventCorrect(Object event) {
		if (event == null) {
			throw new ALModuleException("投递的事件 不能为null");
		}

		if (!modules.containsKey(event.getClass().getSimpleName())) {
			throw new ALModuleException("没有任何模块可处理事件 "
					+ event.getClass().getSimpleName());
		}
	}

	/**
	 * 将UI投递到模块管理器的事件分发到指定模块
	 * 
	 * @param event
	 */
	private synchronized void invokePostEventToModule(Object event) {
		// 首先检查收到的事件是否正确
		isPostingEventCorrect(event);
		BaseModule module = modules.get(event.getClass().getSimpleName());
		ALLog.d("开始投递事件到 " + module.getClass().getSimpleName() + " 模块");
		module.onModuleManagerEvent(event);
	}
	/******************************************* 私有方法结束 **********************************************/
}
